#include "Game.h"

#include "../SGD Wrappers/SGD_AudioManager.h"
#include "../SGD Wrappers/SGD_GraphicsManager.h"
#include "../SGD Wrappers/SGD_InputManager.h"
#include "../SGD Wrappers/SGD_String.h"
#include "..\SGD Wrappers\SGD_MessageManager.h"

#include "Message Management\MessageID.h"
#include "Message Management\CreatePlaysoundMessage.h"
#include "Message Management\CreateAddPowerUpMessage.h"
#include "Message Management\DeleteObjectMessage.h"

#include "Tile Management\\TileManager.h"
#include "Sprite Management\\AnimationManager.h"
#include "AI States\AIManagerState.h"
#include "AI States\AIState.h"
#include "Game Objects\Player.h"
#include "Game Objects\CrumblingPlatformObject.h"
#include "Game Objects\DestructableObject.h"
#include "Game Objects\SwitchTriggerObject.h"
#include "Game Objects\WallTriggerObject.h"
#include "Game States\IGameState.h"
#include "Game States\SplashState.h"
#include "Game States\GamePlayState.h"
#include "Game Objects\Enemy.h"
#include "Game Objects\PowerUps.h"
#include "Game Objects\\Projectile.h"
#include "Game Objects\\CheckPointObject.h"
#include "Game Objects\\SpikeObject.h"
#include "Game Objects\\SpringboardObject.h"
#include "Game Objects\\Event.h"
#include "Game Objects\\Liquid.h"
#include "Game Objects\Boss.h"

#include "Bitmap Font\BitmapFont.h"

#include "Definitions.h"

#include <ctime>
#include <cstdlib>
#include <fstream>
#include <cassert>
#include <ShlObj.h>
#include <string>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

#include <fstream>

Game* Game::spInstance = nullptr;			// SINGLETON

// Testing netrc comment

Game* Game::GetInstance(void)
{
	if (spInstance == nullptr)
	{
		spInstance = new Game;
	}
	return spInstance;
}

void Game::DeleteInstance(void)
{
	delete spInstance;
	spInstance = nullptr;
}

bool Game::Initialize(float width, float height)
{
	srand((unsigned int)time(nullptr));		// Seed Random Generator

	// Initialize the Message Manager
	SGD::MessageManager::GetInstance()->Initialize(&Game::MessageProc);
	
	
	// Initialize the wrappers
	if (AUDIO->Initialize() == false
		|| GRAPHICS->Initialize(false) == false
		|| SGD::InputManager::GetInstance()->Initialize() == false)
		return false;

	// Set Save File Paths
	HRESULT hr;
	LPWSTR wszPath = nullptr;
	size_t size;
	char path[MAX_PATH];

	// Get path to APPData
	hr = SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, 0, &wszPath);

	// Convert from LPWSTR to char[]
	wcstombs_s(&size, path, MAX_PATH, wszPath, MAX_PATH);

	// Convert char types
	if (hr == S_OK)
		woFilePathStream << path;

	// Add Team Name and Game Name
	woFilePathStream << L"\\Team Faultline\\Fantasy Fall";
	std::wstring filePath = woFilePathStream.str();

	// Create directory if it doesn't exist
	SHCreateDirectoryEx(NULL, filePath.c_str(), 0);

	filePath += L"\\options.txt";

	// Load Audio Volumes
	std::fstream file;
	file.open(filePath.c_str(), std::ios_base::in);
	if (file.is_open())
	{
		int nMusVol, nSfxVol;
		file >> nMusVol;
		file.ignore(INT_MAX, '\n');
		file >> nSfxVol;
		file.ignore(INT_MAX, '\n');
		file >> bFullScreen;
		file.ignore(INT_MAX, '\n');

		SetMusicVolume(nMusVol);
		SetSfxVolume(nSfxVol);
		file.close();
	}

	// Set Audio Levels
	AUDIO->SetMasterVolume(SGD::AudioGroup::Music, GetMusicVolume());
	AUDIO->SetMasterVolume(SGD::AudioGroup::SoundEffects, GetSfxVolume());

	// Set Fullscreen
	GRAPHICS->Resize(SGD::Size{ width, height }, !bFullScreen);

	// Load Audio
	hEnemyAttackSfx = AUDIO->LoadAudio("Resource/Audio/EnemyAttack.wav");
	hEnemyHurtSfx = AUDIO->LoadAudio("Resource/Audio/EnemyHurt.wav");
	hPlayerAttackSfx = AUDIO->LoadAudio("Resource/Audio/PlayerAttack.wav");
	hPlayerHurtSfx = AUDIO->LoadAudio("Resource/Audio/PlayerHurt.wav");
	hPlayerJumpSfx = AUDIO->LoadAudio("Resource/Audio/PlayerJump.wav");
	hPickupSfx = AUDIO->LoadAudio("Resource/Audio/PlayerPickup.wav");
	hSwitchSfx = AUDIO->LoadAudio("Resource/Audio/ButtonPush.wav");
	hCheckPointSfx = AUDIO->LoadAudio("Resource/Audio/CheckPoint.wav");
	hSpringboardSfx = AUDIO->LoadAudio("Resource/Audio/Springboard.wav");

	// Load Images
	hTeamLogoImage = GRAPHICS->LoadTexture(L"Resource/Images/TeamLogo.png");
	hFantasyFallLogoImage = GRAPHICS->LoadTexture(L"Resource/Images/FantasyFallLogo.png");
	hPauseBackgroundImage = GRAPHICS->LoadTexture(L"Resource/Images/PauseMenu.png");
	hOptionsImage = GRAPHICS->LoadTexture(L"Resource/Images/OptionsMenu.png");

	hPlayerImage = GRAPHICS->LoadTexture(L"Resource/Images/cheetahcells.png"); // Player animations and Head Icon
	hEnemyImage = GRAPHICS->LoadTexture(L"Resource/Images/badgersheet.png");
	//hBossImage = GRAPHICS->LoadTexture(L"Resource/Images/LilPrick.png");
	hProjectileImage = GRAPHICS->LoadTexture(L"Resource/Images/boulder.png");
	//hDestructableImage = GRAPHICS->LoadTexture(L"Resource/Images/Destructable.png");
	hHPBoostImage = GRAPHICS->LoadTexture(L"Resource/Images/hpboost.png");
	hDamageBoostImage = GRAPHICS->LoadTexture(L"Resource/Images/strengthboost.png");
	hSpeedBoostImage = GRAPHICS->LoadTexture(L"Resource/Images/speedboost.png");
	hCheckPointImage = GRAPHICS->LoadTexture(L"Resource/Images/checkpoint.png");
	hCrumblingPlatformImage = GRAPHICS->LoadTexture(L"Resource/Images/crumblingplatform.png");
	hSwitchImage = GRAPHICS->LoadTexture(L"Resource/Images/switch.png");
	hWallTriggerImage = GRAPHICS->LoadTexture(L"Resource/Images/walltriggerobject.png");
	hSpikeImage = GRAPHICS->LoadTexture(L"Resource/Images/Spike.png");
	hSpringboardImage = GRAPHICS->LoadTexture(L"Resource/Images/Springboard.png");
	hPapaBearImage = GRAPHICS->LoadTexture(L"Resource/Images/bearsheet.png");
	hLockJawImage = GRAPHICS->LoadTexture(L"Resource/Images/lockjaw.png");
	hQudzuImage = GRAPHICS->LoadTexture(L"Resource/Images/plantsheet.png");
	hLavaImage = GRAPHICS->LoadTexture(L"Resource/Images/lava.png");
	hWaterImage = GRAPHICS->LoadTexture(L"Resource/Images/water.png");
	hQuicksandImage = GRAPHICS->LoadTexture(L"Resource/Images/quicksand.png");
	hQuicksandSurfaceImage = GRAPHICS->LoadTexture(L"Resource/Images/quicksandsurface.png");

	fScreenWidth = width;					// Store screen width
	fScreenHeight = height;					// Store screen height

	// Load AI Manager
	AIManager = new AIManagerState;

	// Load Tile Manager
	tileManager = new TileManager;

	// Load Animation Manager
	AnimManager = new AnimationManager;
	LoadAnimations();

	// Load Particle Manager
	particleManager = new ParticleManager;
	particleManager->LoadEmitters("Resource\\playerBlood.xml");

	// Load Bitmap Font
	bitFont = new BitmapFont;
	bitFont->Initialize("Resource\\Images\\Bonzai.png", "Resource\\Bonzai.txt");

	LoadHighScores();

	SortHighScores();

	// Start Game in Main Menu State
	ChangeState(SplashState::GetInstance());
	//ChangeState(GamePlayState::GetInstance());

	ulGameTime = GetTickCount();			// Store the current time (in milliseconds)

	SetPlayerLives(3);

	// Set Check Point to false
	bCheckpoint = false;

	return true;
}

int Game::Update(void)
{
	// Update the wrappers
	if (AUDIO->Update() == false
		|| GRAPHICS->Update() == false
		|| SGD::InputManager::GetInstance()->Update() == false)
		return -10;		// exit FAILURE!

	if (ARCADE && SGD::InputManager::GetInstance()->GetLeftJoystick(0) == SGD::Vector(0.0f, 0.0f))
		GAME->SetInput(true);

	if (SGD::InputManager::GetInstance()->IsKeyDown(SGD::Key::Alt)
		&& SGD::InputManager::GetInstance()->IsKeyPressed(SGD::Key::Enter))
	{
		bFullScreen = !bFullScreen;
		GRAPHICS->Resize({ fScreenWidth, fScreenHeight }, bFullScreen);
		return 0;
	}

	// Calculate the elapsed time between frames
	unsigned long now = GetTickCount();					// current time in milliseconds
	elapsedTime = (now - ulGameTime) / 1000.0f;	// convert to fraction of a second
	ulGameTime = now;									// store the current time

	// Cap the elapsed time to 1/8th of a second
	if (elapsedTime > 0.125f)
		elapsedTime = 0.125f;
	
	if (pCurState == nullptr)
		return -20;


	// Let the current state handle input
	if (pCurState->Update(elapsedTime) == false)
		return 1;	// exit success!

	// Let the current state render
	pCurState->Render();

	// Run Update on Messages
	SGD::MessageManager::GetInstance()->Update();

	return 0;		// keep playing!
}

void Game::Terminate(void)
{
	// Exit the current state
	ChangeState(nullptr);

	// Unload Audio Asset
	AUDIO->UnloadAudio(hEnemyAttackSfx);
	AUDIO->UnloadAudio(hEnemyHurtSfx);
	AUDIO->UnloadAudio(hPlayerAttackSfx);
	AUDIO->UnloadAudio(hPlayerHurtSfx);
	AUDIO->UnloadAudio(hPlayerJumpSfx);
	AUDIO->UnloadAudio(hPickupSfx);
	AUDIO->UnloadAudio(hCheckPointSfx);
	AUDIO->UnloadAudio(hSpringboardSfx);
	AUDIO->UnloadAudio(hSwitchSfx);
	
	if (hBackgroundMus != SGD::INVALID_HANDLE)
		AUDIO->UnloadAudio(hBackgroundMus);

	// Delete AI Manager
	delete AIManager;
	AIManager = nullptr;

	// Delete Tile Manager
	delete tileManager;

	// Delete Animation Manager
	delete AnimManager;
	AnimManager = nullptr;

	// Delete emitters
	delete particleManager;

	// Delete Bitmap
	bitFont->Terminate();
	delete bitFont;

	// Clear entity manager
	pObjects.RemoveAll();

	SaveHighScores();

	vecHighScores.clear();

	// Unload Assets
	GRAPHICS->UnloadTexture(hTeamLogoImage);
	GRAPHICS->UnloadTexture(hFantasyFallLogoImage);
	GRAPHICS->UnloadTexture(hPauseBackgroundImage);
	GRAPHICS->UnloadTexture(hOptionsImage);

	GRAPHICS->UnloadTexture(hBackground);
	GRAPHICS->UnloadTexture(hPauseBackground);
	GRAPHICS->UnloadTexture(hPlayerImage);
	GRAPHICS->UnloadTexture(hEnemyImage);
	GRAPHICS->UnloadTexture(hBossImage);
	GRAPHICS->UnloadTexture(hProjectileImage);
	GRAPHICS->UnloadTexture(hHPBoostImage);
	GRAPHICS->UnloadTexture(hSpeedBoostImage);
	GRAPHICS->UnloadTexture(hDamageBoostImage);
	GRAPHICS->UnloadTexture(hCheckPointImage);
	GRAPHICS->UnloadTexture(hCrumblingPlatformImage);
	GRAPHICS->UnloadTexture(hSwitchImage);
	GRAPHICS->UnloadTexture(hWallTriggerImage);
	GRAPHICS->UnloadTexture(hSpikeImage);
	GRAPHICS->UnloadTexture(hSpringboardImage);
	GRAPHICS->UnloadTexture(hPapaBearImage);
	GRAPHICS->UnloadTexture(hLockJawImage);
	GRAPHICS->UnloadTexture(hQudzuImage);
	GRAPHICS->UnloadTexture(hLavaImage);
	GRAPHICS->UnloadTexture(hWaterImage);
	GRAPHICS->UnloadTexture(hQuicksandImage);
	GRAPHICS->UnloadTexture(hQuicksandSurfaceImage);

	if (pPlayer != nullptr)
		pPlayer->Release();

	// Terminate the core SGD wrappers
	AUDIO->Terminate();
	SGD::AudioManager::DeleteInstance();

	SGD::InputManager::GetInstance()->Terminate();
	SGD::InputManager::DeleteInstance();

	SGD::MessageManager::GetInstance()->Terminate();
	SGD::MessageManager::DeleteInstance();

	GRAPHICS->Terminate();
	SGD::GraphicsManager::DeleteInstance();
}

void Game::MessageProc(const SGD::Message* pMsg)
{
	// Detect Message Type
	if (pMsg->GetMessageID() == MessageID::MSG_ADD_POWER_UP)
	{
		const CreateAddPowerUpMessage* powerAdd = dynamic_cast<const CreateAddPowerUpMessage*>(pMsg);
		PowerUps* powerUp = dynamic_cast<PowerUps*>(powerAdd->GetOwner());
		const int iDam = powerUp->GetDamagePowerUp();
		const int iHP = powerUp->GetHPPowerUp();
		const float fSpeed = powerUp->GetSpeedPowerUp();
		GamePlayState::GetInstance()->SetPlayerPowerUps(iDam, iHP, fSpeed);

		// Delete PowerUp
		GAME->GetEntityManager().RemoveEntity(powerUp);
	}
	if(pMsg->GetMessageID() == MessageID::MSG_DELETE_OBJECT)
	{
		const DeleteObjectMessage* delObject = dynamic_cast<const DeleteObjectMessage*>(pMsg);
		
		// Check if object is a Crumbling Platform
		if (delObject->GetOwner()->GetID() == GameObject::ObjectID::CRUMBLING_PLATFORM)
		{
			// Get Crumbling Platform
			CrumblingPlatformObject* crumblingPlatform = dynamic_cast<CrumblingPlatformObject*>(delObject->GetOwner());
			
			// Delete Crumbling Platform
			GAME->GetEntityManager().RemoveEntity(crumblingPlatform);
		}
		// Check if object is a Switch Trigger Object
		else if (delObject->GetOwner()->GetID() == GameObject::ObjectID::SWITCH_TRIGGER)
		{
			// Get Destructable Object
			SwitchTriggerObject* switchObject = dynamic_cast<SwitchTriggerObject*>(delObject->GetOwner());

			std::vector<WallTriggerObject*> wallObjects = GAME->GetWallTriggerObjectsVector();

			for (unsigned int i = 0; i < wallObjects.size(); i++)
			{
				if (switchObject->GetTargetID() == wallObjects[i]->GetOwnerID())
					GAME->GetEntityManager().RemoveEntity(wallObjects[i]);
			}
		}
		else if (delObject->GetOwner()->GetID() == GameObject::ObjectID::MELEE
			|| delObject->GetOwner()->GetID() == GameObject::ObjectID::RANGED)
		{
			// Get Melee enemy
			Enemy* enemy = dynamic_cast<Enemy*>(delObject->GetOwner());
			// Remove From Entity Manager
			GAME->GetEntityManager().RemoveEntity(enemy);
		}
		else if (delObject->GetOwner()->GetID() == GameObject::ObjectID::PROJECTILE)
		{
			Projectile* proj = dynamic_cast<Projectile*>(delObject->GetOwner());

			GAME->GetEntityManager().RemoveEntity(proj);
		}
	}
}

void Game::ChangeState(IGameState* pNewState)
{
	// Set Next state to new state
	pNextState = pNewState;

	// Exit the old state
	if (pCurState != nullptr)
		pCurState->Exit();

	// Store the new state
	pCurState = pNewState;

	// Enter the new state
	if (pCurState != nullptr)
		pCurState->Enter();

	// Set Next state back to null
	pNextState = nullptr;
}

AIManagerState* Game::GetAIManager()
{
	return AIManager;
}

std::vector<WallTriggerObject*> Game::GetWallTriggerObjectsVector()
{
	return wallTriggerObjects;
}
void Game::SetWallTriggerObjectsVector(std::vector<WallTriggerObject*> wallObjects)
{
	wallTriggerObjects = wallObjects;
}

void Game::SetMusicVolume(int volume)
{
	if (volume < 0)
		cMusicVolume = 0;
	else if (volume > 100)
		cMusicVolume = 100;
	else
		cMusicVolume = volume;
}

void Game::SetSfxVolume(int volume)
{
	if (volume < 0)
		cSfxVolume = 0;
	else if (volume > 100)
		cSfxVolume = 100;
	else
		cSfxVolume = volume;
}

void Game::SetFullScreen(bool bFullscreen)
{
	bFullScreen = bFullscreen;
}

void Game::SaveGame()
{
	std::wstring filePath = GetFilePath();
	filePath += L"\\file";
	filePath += (char)(iProfile + 48);
	filePath += L".save";

	std::fstream file;

	if (GAME->GetStageCompleted() == 4)
		GAME->SetCurrentLevel(5);

	// Save Data
	file.open(filePath.c_str(), std::ios_base::out | std::ios_base::binary);
	if (file.is_open())
	{
		file.write((char*)&iCurrentLevel, 4);
		file.close();
	}

	filePath.clear();
}

/*******************************************/
// GamePlayState Variable Accessors/Mutators

// Accessors
bool Game::GetVillagerSaved(unsigned int stage, unsigned int number)
{
	switch (stage)
	{
	case 1:
	{
		switch (number)
		{
		case 1:
		{
			return bVillager1_1;
		}
		default:
		{
			return false;
		}
		}
	}
	case 2:
	{
		switch (number)
		{
		case 1:
		{
			return bVillager2_1;
		}
		default:
		{
			return false;
		}
		}
	}
	case 3:
	{
		switch (number)
		{
		case 1:
		{
			return bVillager3_1;
		}
		default:
		{
			return false;
		}
		}
	}
	case 4:
	{
		switch (number)
		{
		case 1:
		{
			return bVillager4_1;
		}
		default:
		{
			return false;
		}
		}
	}
	default:
	{
		return false;
	}
	}
}

unsigned int Game::GetStageCompleted()
{
	return iStageComplete;
}

bool Game::GetCheckpoint()
{
	return bCheckpoint;
}

int Game::GetPlayerLives()
{
	return iPlayerLives;
}

// Mutators
void Game::SetVillagerSaved(unsigned int stage, unsigned int number, bool saved)
{
	switch (stage)
	{
	case 1:
	{
		switch (number)
		{
		case 1:
		{
			bVillager1_1 = saved;
			break;
		}
		}
	}
	case 2:
	{
		switch (number)
		{
		case 1:
		{
			bVillager2_1 = saved;
			break;
		}
		}
	}
	case 3:
	{
		switch (number)
		{
		case 1:
		{
			bVillager3_1 = saved;
			break;
		}
		}
	}
	case 4:
	{
		switch (number)
		{
		case 1:
		{
			bVillager4_1 = saved;
			break;
		}
		}
	}
	}
}

void Game::SetStageCompleted(unsigned int stage)
{
	iStageComplete = stage;
}

void Game::SetCheckpoint(bool checkpoint)
{
	bCheckpoint = checkpoint;
}

void Game::SetPlayerLives(unsigned int lives)
{
	iPlayerLives = lives;
}

int Game::GetCurrentProfile()
{
	return iProfile;
}

void Game::SetCurrentProfile(int profile)
{
	iProfile = profile;
}

unsigned int Game::GetCurrentLevel()
{
	return iCurrentLevel;
}

void Game::SetCurrentLevel(unsigned int level)
{
	iCurrentLevel = level;
}

std::wstring Game::GetFilePath()
{
	return woFilePathStream.str();
}

Player* Game::GetPlayer()
{
	return pPlayer;
}

void Game::SetPlayer(Player* player)
{
	if (pPlayer != nullptr)
		pPlayer->Release();
	pPlayer = player;
}

EntityManager& Game::GetEntityManager()
{
	return pObjects;
}

TileManager* Game::GetTileManager()
{
	return tileManager;
}

BitmapFont* Game::GetBitmapFont()
{
	return bitFont;
}

void Game::PlayEnemyAttackAudio()
{
	if (!AUDIO->IsAudioPlaying(hEnemyAttackSfx))
		AUDIO->PlayAudio(hEnemyAttackSfx);
}

void Game::PlayEnemyHurtAudio()
{
	if (!AUDIO->IsAudioPlaying(hEnemyHurtSfx))
		AUDIO->PlayAudio(hEnemyHurtSfx);
}

void Game::PlayPlayerAttackAudio()
{
	if (!AUDIO->IsAudioPlaying(hPlayerAttackSfx))
		AUDIO->PlayAudio(hPlayerAttackSfx);
}

void Game::PlayPlayerHurtAudio()
{
	if (!AUDIO->IsAudioPlaying(hPlayerHurtSfx))
		AUDIO->PlayAudio(hPlayerHurtSfx);
}

void Game::PlayPlayerJumpAudio()
{
	if (!AUDIO->IsAudioPlaying(hPlayerJumpSfx))
		AUDIO->PlayAudio(hPlayerJumpSfx);
}

void Game::PlayPickupAudio()
{
	if (!AUDIO->IsAudioPlaying(hPickupSfx))
		AUDIO->PlayAudio(hPickupSfx);
}

void Game::PlaySwitchAudio()
{
	if (!AUDIO->IsAudioPlaying(hSwitchSfx))
		AUDIO->PlayAudio(hSwitchSfx);
}

void Game::PlayCheckPointAudio()
{
	if (!AUDIO->IsAudioPlaying(hCheckPointSfx))
		AUDIO->PlayAudio(hCheckPointSfx);
}


void Game::PlaySpringboardAudio()
{
	if (!AUDIO->IsAudioPlaying(hSpringboardSfx))
		AUDIO->PlayAudio(hSpringboardSfx);
}

AnimationManager* Game::GetAnimationManager()
{
	return AnimManager;
}

void Game::LoadAnimations()
{
	AnimationManager* am = GAME->GetAnimationManager();
	Animation animation;
	animation.SetImage(hPlayerImage);

	// Player
	// Create First animation - This is the waiting animation
	animation.AddFrame(Frame({ 128.0f, 92.0f }, { 103.0f, 18.0f, 147.0f, 96.0f }, { 111.0f, 18.0f, 144.0f, 96.0f }, 0.0f, 3.0f, -1));
	animation.AddFrame(Frame({ 192.0f, 92.0f }, { 166.0f, 18.0f, 211.0f, 96.0f }, { 174.0f, 18.0f, 208.0f, 96.0f }, 0.0f, .25f, -1));
	animation.AddFrame(Frame({ 256.0f, 92.0f }, { 230.0f, 18.0f, 275.0f, 96.0f }, { 239.0f, 18.0f, 272.0f, 96.0f }, 0.0f, .25f, -1));
	// Insert animation into animation manager
	am->AddAnimation("PlayerIdleRight", animation);
	// Clean temp animation
	animation.Clear();
	// Create First animation - This is the waiting animation
	animation.AddFrame(Frame({ 128.0f, 92.0f }, { 103.0f, 18.0f, 147.0f, 96.0f }, { 111.0f, 18.0f, 144.0f, 96.0f }, 0.0f, 3.0f, -1, true));
	animation.AddFrame(Frame({ 192.0f, 92.0f }, { 166.0f, 18.0f, 211.0f, 96.0f }, { 174.0f, 18.0f, 208.0f, 96.0f }, 0.0f, .25f, -1, true));
	animation.AddFrame(Frame({ 256.0f, 92.0f }, { 230.0f, 18.0f, 275.0f, 96.0f }, { 239.0f, 18.0f, 272.0f, 96.0f }, 0.0f, .25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("PlayerIdleLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Create Walking Animation
	animation.AddFrame(Frame({ 320.0f, 92.0f}, { 292.0f, 16.0f, 350.0f, 96.0f }, { 300.0f, 16.0f, 349.0f, 96.0f}, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 384.0f, 92.0f}, { 354.0f, 16.0f, 399.0f, 96.0f }, { 372.0f, 16.0f, 399.0f, 96.0f}, 0.0f, 0.2f, -1));
	animation.AddFrame(Frame({ 448.0f, 92.0f}, { 424.0f, 16.0f, 478.0f, 96.0f }, { 430.0f, 16.0f, 477.0f, 96.0f}, 0.0f, 0.1f, -1));
	// Insert animation into animation manager
	am->AddAnimation("PlayerWalkRight", animation);
	// Clean temp animation
	animation.Clear();
	// Create Walking Animation
	animation.AddFrame(Frame({ 320.0f, 92.0f }, { 292.0f, 16.0f, 350.0f, 96.0f }, { 300.0f, 16.0f, 349.0f, 96.0f }, 0.0f, 0.1f, -1, true));
	animation.AddFrame(Frame({ 384.0f, 92.0f }, { 354.0f, 16.0f, 399.0f, 96.0f }, { 372.0f, 16.0f, 399.0f, 96.0f }, 0.0f, 0.2f, -1, true));
	animation.AddFrame(Frame({ 448.0f, 92.0f }, { 424.0f, 16.0f, 478.0f, 96.0f }, { 430.0f, 16.0f, 477.0f, 96.0f }, 0.0f, 0.1f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("PlayerWalkLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Create Start Running animation
	animation.AddFrame(Frame({544.0f, 92.0f}, { 514.0f, 30.0f, 578.0f, 96.0f }, { 514.0f, 30.0f, 576.0f, 96.0f }, 0.0f, 0.25f, -1));
	// Insert animation into the animation manager
	am->AddAnimation("PlayerStartRunning", animation);
	// Clean temp animation
	animation.Clear();
	// Create Second Animation - This is the Running Animation
	animation.AddFrame(Frame({ 632.0f, 96.0f }, { 591.0f, 20.0f, 656.0f, 96.0f }, { 600.0f, 20.0f, 657.0f, 96.0f }, 0.0f, .20f, -1));
	animation.AddFrame(Frame({ 697.0f, 96.0f }, { 671.0f, 20.0f, 720.0f, 86.0f }, { 683.0f, 20.0f, 721.0f, 86.0f }, 0.0f, .20f, -1));
	animation.AddFrame(Frame({ 760.0f, 96.0f }, { 723.0f, 20.0f, 785.0f, 96.0f }, { 733.0f, 20.0f, 785.0f, 96.0f }, 0.0f, .20f, -1));
	// Insert animation into animation manager
	am->AddAnimation("PlayerRunRight", animation);
	// Clean temp animation
	animation.Clear();
	// Create Second Animation - This is the Running Animation
	animation.AddFrame(Frame({ 632.0f, 96.0f }, { 591.0f, 20.0f, 656.0f, 96.0f }, { 600.0f, 20.0f, 657.0f, 96.0f }, 0.0f, .20f, -1, true));
	animation.AddFrame(Frame({ 697.0f, 96.0f }, { 671.0f, 20.0f, 720.0f, 86.0f }, { 683.0f, 20.0f, 721.0f, 86.0f }, 0.0f, .20f, -1, true));
	animation.AddFrame(Frame({ 760.0f, 96.0f }, { 723.0f, 20.0f, 785.0f, 96.0f }, { 733.0f, 20.0f, 785.0f, 96.0f }, 0.0f, .20f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("PlayerRunLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Create Third Animation - This is the jumping animation
	animation.AddFrame(Frame({ 36.0f, 192.0f }, { 3.0f, 112.0f, 61.0f, 192.0f }, { 12.0f, 113.0f, 62.0f, 192.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 96.0f, 192.0f }, { 64.0f, 120.0f, 131.0f, 186.0f }, { 67.0f, 126.0f, 132.0f, 186.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 160.0f, 192.0f }, { 138.0f, 123.0f, 192.0f, 189.0f }, { 148.0f, 130.0f, 186.0f, 187.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 224.0f, 192.0f }, { 196.0f, 135.0f, 262.0f, 188.0f }, { 225.0f, 128.0f, 248.0f, 186.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 288.0f, 192.0f }, { 265.0f, 126.0f, 318.0f, 191.0f }, { 267.0f, 128.0f, 314.0f, 185.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 352.0f, 192.0f }, { 323.0f, 131.0f, 389.0f, 185.0f }, { 330.0f, 134.0f, 378.0f, 175.0f }, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 448.0f, 192.0f }, { 416.0f, 129.0f, 486.0f, 189.0f }, { 423.0f, 132.0f, 474.0f, 189.0f }, 0.0f, .15f, -1));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerJumpRight", animation);
	// Clean temp animation
	animation.Clear();
	// Create Third Animation - This is the jumping animation
	animation.AddFrame(Frame({ 36.0f, 192.0f }, { 3.0f, 112.0f, 61.0f, 192.0f }, { 12.0f, 113.0f, 62.0f, 192.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 96.0f, 192.0f }, { 64.0f, 120.0f, 131.0f, 186.0f }, { 67.0f, 126.0f, 132.0f, 186.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 160.0f, 192.0f }, { 138.0f, 123.0f, 192.0f, 189.0f }, { 148.0f, 130.0f, 186.0f, 187.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 224.0f, 192.0f }, { 196.0f, 135.0f, 262.0f, 188.0f }, { 225.0f, 128.0f, 248.0f, 186.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 288.0f, 192.0f }, { 265.0f, 126.0f, 318.0f, 191.0f }, { 267.0f, 128.0f, 314.0f, 185.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 352.0f, 192.0f }, { 323.0f, 131.0f, 389.0f, 185.0f }, { 330.0f, 134.0f, 378.0f, 175.0f }, 0.0f, .15f, -1, true));
	animation.AddFrame(Frame({ 448.0f, 192.0f }, { 416.0f, 129.0f, 486.0f, 189.0f }, { 423.0f, 132.0f, 474.0f, 189.0f }, 0.0f, .15f, -1, true));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerJumpLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Create Fourth Animation - This is the attacking animation
	animation.AddFrame(Frame({ 64.0f, 289.0f }, { 33.0f, 217.0f, 99.0f, 289.0f }, { 34.0f, 217.0f, 98.0f, 289.0f }, 0.0f, 0.0f, -1));
	animation.AddFrame(Frame({ 160.0f, 289.0f }, { 129.0f, 217.0f, 195.0f, 289.0f }, { 129.0f, 217.0f, 194.0f, 289.0f }, 0.0f, 0.10f, -1));
	animation.AddFrame(Frame({ 256.0f, 289.0f }, { 220.0f, 207.0f, 314.0f, 290.0f }, { 222.0f, 217.0f, 291.0f, 290.0f }, 0.0f, 0.10f, -1));
	animation.AddFrame(Frame({ 384.0f, 289.0f }, { 350.0f, 210.0f, 419.0f, 290.0f }, { 350.0f, 217.0f, 419.0f, 290.0f }, 0.0f, 0.0f, -1));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerAttackRight", animation);
	// Clean temp animation
	animation.Clear();
	// Create Fourth Animation - This is the attacking animation
	animation.AddFrame(Frame({ 64.0f, 289.0f }, { 33.0f, 217.0f, 99.0f, 289.0f }, { 34.0f, 217.0f, 98.0f, 289.0f }, 0.0f, 0.0f, -1, true));
	animation.AddFrame(Frame({ 160.0f, 289.0f }, { 129.0f, 217.0f, 195.0f, 289.0f }, { 129.0f, 217.0f, 194.0f, 289.0f }, 0.0f, 0.10f, -1, true));
	animation.AddFrame(Frame({ 256.0f, 289.0f }, { 220.0f, 207.0f, 314.0f, 290.0f }, { 222.0f, 217.0f, 291.0f, 290.0f }, 0.0f, 0.10f, -1, true));
	animation.AddFrame(Frame({ 384.0f, 289.0f }, { 350.0f, 210.0f, 419.0f, 290.0f }, { 350.0f, 217.0f, 419.0f, 290.0f }, 0.0f, 0.0f, -1, true));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerAttackLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Create Fifth Animation - This is the attacking up animation
	animation.AddFrame(Frame({ 32.0f, 480.0f }, { 3.0f, 412.0f, 57.0f, 480.0f }, { 7.0f, 412.0f, 57.0f, 480.0f }, 0.0f, .25f, -1));
	animation.AddFrame(Frame({ 111.0f, 480.0f }, { 78.0f, 412.0f, 146.0f, 480.0f }, { 79.0f, 412.0f, 146.0f, 480.0f }, 0.0f, .25f, -1));
	animation.AddFrame(Frame({ 209.0f, 480.0f }, { 164.0f, 324.0f, 255.0f, 480.0f }, { 175.0f, 412.0f, 240.0f, 480.0f }, 0.0f, .25f, -1));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerAttackUp", animation);
	// Clean temp animation
	animation.Clear();
	// Create Sixth Animation - This is the attacking down animation
	animation.AddFrame(Frame({ 352.0f, 384.0f }, { 320.0f, 327.0f, 384.0f, 384.0f }, { 336.0f, 327.0f, 369.0f, 384.0f }, 0.0f, .25f, -1));
	animation.AddFrame(Frame({ 448.0f, 384.0f }, { 403.0f, 327.0f, 488.0f, 475.0f }, { 431.0f, 327.0f, 446.0f, 384.0f }, 0.0f, .25f, -1));
	animation.AddFrame(Frame({ 544.0f, 384.0f }, { 511.0f, 327.0f, 594.0f, 384.0f }, { 527.0f, 324.0f, 561.0f, 384.0f }, 0.0f, .25f, -1));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerAttackDown", animation);
	// Clean temp animation
	animation.Clear();
	// Create Seventh Animation - This is the dying animation
	animation.AddFrame(Frame({ 32.0f, 612.0f }, { 25.0f, 569.0f, 39.0f, 584.0f }, {}, 0.0f, .05f, -1));
	animation.AddFrame(Frame({ 64.0f, 612.0f }, { 54.0f, 567.0f, 74.0f, 587.0f }, {}, 0.0f, .05f, -1));
	animation.AddFrame(Frame({ 96.0f, 612.0f }, { 79.0f, 558.0f, 113.0f, 593.0f }, {}, 0.0f, .05f, -1));
	animation.AddFrame(Frame({ 160.0f, 612.0f }, { 127.0f, 545.0f, 192.0f, 602.0f }, {}, 0.0f, .05f, -1));
	animation.AddFrame(Frame({ 256.0f, 612.0f }, { 221.0f, 544.0f, 293.0f, 614.0f }, {}, 0.0f, .05f, -1));
	animation.AddFrame(Frame({ 352.0f, 612.0f }, { 319.0f, 563.0f, 385.0f, 614.0f }, {}, 0.0f, .15f, -1));
	animation.AddFrame(Frame({ 416.0f, 612.0f }, { 397.0f, 588.0f, 434.0f, 616.0f }, {}, 0.0f, 2.0f, -1));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("PlayerDeath", animation);
	// Clean temp animation
	animation.Clear();

	// Springboard
	// Set Image
	animation.SetImage(hSpringboardImage);
	animation.AddFrame(Frame({ 0.0f, 31.0f }, { 0.0f, 0.0f, 31.0f, 31.0f }, { 0.0f, 0.0f, 31.0f, 31.0f }));
	// Insert animation into animation manager
	am->AddAnimation("Springboard", animation);
	// Clean temp animation
	animation.Clear();

	// Switch Trigger Object
	// Set Image
	animation.SetImage(hSwitchImage);
	// - Switch Up
	animation.AddFrame(Frame({ 0.0f, 16.0f }, { 0.0f, 0.0f, 32.0f, 16.0f }, { 0.0f, 0.0f, 32.0f, 16.0f }, 0.0f, 0.0f, -1));
	// Insert animation into animation manager
	am->AddAnimation("SwitchTriggerUp", animation);
	// Clean temp animation
	animation.Clear();
	// - Switch Down
	animation.AddFrame(Frame({ 32.0f, 16.0f }, { 33.0f, 5.0f, 64.0f, 16.0f }, { 33.0f, 5.0f, 64.0f, 16.0f }, 0.0f, 0.0f, -1));
	// Insert animation into animation manager
	am->AddAnimation("SwitchTriggerDown", animation);
	// Clean temp animation
	animation.Clear();

	// Wall Trigger Object
	// Set Image
	animation.SetImage(hWallTriggerImage);
	// Add Frame
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }));
	// Insert animation into animation manager
	am->AddAnimation("WallTrigger", animation);
	// Clean temp animation
	animation.Clear();


	// Qudzu
	// Set Image
	animation.SetImage(hQudzuImage);
	// Idle Left
	animation.AddFrame(Frame({ 64.0f, 95.0f }, { 18.0f, 11.0f, 103.0f, 95.0f }, { 48.0f, 11.0f, 89.0f, 95.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 160.0f, 95.0f }, { 113.0f, 14.0f, 198.0f, 95.0f }, { 143.0f, 14.0f, 186.0f, 95.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("QudzuIdleLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Idle Right
	animation.AddFrame(Frame({ 64.0f, 95.0f }, { 18.0f, 11.0f, 103.0f, 95.0f }, { 48.0f, 11.0f, 89.0f, 95.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 160.0f, 95.0f }, { 113.0f, 14.0f, 198.0f, 95.0f }, { 143.0f, 14.0f, 186.0f, 95.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("QudzuIdleRight", animation);
	// Clean temp animation
	animation.Clear();
	// Walking Left
	animation.AddFrame(Frame({ 64.0f, 256.0f }, { 18.0f, 171.0f, 103.0f, 256.0f }, { 48.0f, 171.0f, 91.0f, 256.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 160.0f, 256.0f }, { 115.0f, 171.0f, 202.0f, 256.0f }, { 150.0f, 171.0f, 197.0f, 256.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("QudzuWalkLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Walking Right
	animation.AddFrame(Frame({ 64.0f, 256.0f }, { 18.0f, 171.0f, 103.0f, 256.0f }, { 48.0f, 171.0f, 91.0f, 256.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 160.0f, 256.0f }, { 115.0f, 171.0f, 202.0f, 256.0f }, { 150.0f, 171.0f, 197.0f, 256.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("QudzuWalkRight", animation);
	// Clean temp animation
	animation.Clear();
	// Attack Left
	animation.AddFrame(Frame({ 288.0f, 256.0f }, { 240.0f, 162.0f, 380.0f, 256.0f }, { 271.0f, 175.0f, 313.0f, 255.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("QudzuAttackLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Attack Right
	animation.AddFrame(Frame({ 288.0f, 256.0f }, { 240.0f, 162.0f, 380.0f, 256.0f }, { 271.0f, 175.0f, 313.0f, 255.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("QudzuAttackRight", animation);
	// Clean temp animation
	animation.Clear();

	// Papa Bear
	// Set Image
	animation.SetImage(hPapaBearImage);
	// Idle Left
	animation.AddFrame(Frame({ 32.0f, 96.0f }, { 7.0f, 12.0f, 76.0f, 96.0f }, { 18.0f, 12.0f, 58.0f, 96.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 128.0f, 96.0f }, { 104.0f, 12.0f, 172.0f, 96.0f }, { 113.0f, 12.0f, 154.0f, 96.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 224.0f, 96.0f }, { 198.0f, 15.0f, 266.0f, 96.0f }, { 209.0f, 15.0f, 246.0f, 96.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("PapaBearIdleLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Idle Right
	animation.AddFrame(Frame({ 32.0f, 96.0f }, { 7.0f, 12.0f, 76.0f, 96.0f }, { 18.0f, 12.0f, 58.0f, 96.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 128.0f, 96.0f }, { 104.0f, 12.0f, 172.0f, 96.0f }, { 113.0f, 12.0f, 154.0f, 96.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 224.0f, 96.0f }, { 198.0f, 15.0f, 266.0f, 96.0f }, { 209.0f, 15.0f, 246.0f, 96.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("PapaBearIdleRight", animation);
	// Clean temp animation
	animation.Clear();
	// Attack Left
	animation.AddFrame(Frame({ 64.0f, 224.0f }, { 30.0f, 142.0f, 123.0f, 224.0f }, { 56.0f, 142.0f, 90.0f, 224.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("PapaBearAttackLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Attack Right
	animation.AddFrame(Frame({ 64.0f, 224.0f }, { 30.0f, 142.0f, 123.0f, 224.0f }, { 56.0f, 142.0f, 90.0f, 224.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("PapaBearAttackRight", animation);
	// Clean temp animation
	animation.Clear();

	// Lock Jaw
	// Set Image
	animation.SetImage(hLockJawImage);
	// Standing Right
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }));
	// Insert animation into animation manager
	am->AddAnimation("LockJawStandingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Standing Left
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }, 0.0f, 0.0f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("LockJawStandingLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Walking Left
	animation.AddFrame(Frame({ 288.0f, 160.0f }, { 208.0f, 28.0f, 352.0f, 160.0f }, { 247.0f, 28.0f, 352.0f, 160.0f }, 0.0f, 0.0f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("LockJawWalkingLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Walking Right
	animation.AddFrame(Frame({ 288.0f, 160.0f }, { 208.0f, 28.0f, 352.0f, 160.0f }, { 247.0f, 28.0f, 352.0f, 160.0f }));
	// Insert animation into animation manager
	am->AddAnimation("LockJawWalkingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Throwing/Hitting Left
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 96.0f, 320.0f }, { 16.0f, 188.0f, 273.0f, 320.0f }, { 55.0f, 188.0f, 160.0f, 320.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animatoin manager
	am->AddAnimation("LockJawAttackingLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Trowing/Hitting Right
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 96.0f, 320.0f }, { 16.0f, 188.0f, 273.0f, 320.0f }, { 55.0f, 188.0f, 160.0f, 320.0f }, 0.0f, 0.25f));
	// Insert animation into animtion manager
	am->AddAnimation("LockJawAttackingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Hitting Ground Left
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 320.0f, 320.0f }, { 280.0f, 187.0f, 495.0f, 364.0f }, { 280.0f, 187.0f, 384.0f, 320.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("LockJawGroundSmashLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Hitting Ground Right
	animation.AddFrame(Frame({ 96.0f, 160.0f }, { 5.0f, 14.0f, 184.0f, 160.0f }, { 55.0f, 14.0f, 137.0f, 160.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 320.0f, 320.0f }, { 280.0f, 187.0f, 495.0f, 364.0f }, { 280.0f, 187.0f, 384.0f, 320.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("LockJawGroundSmashRight", animation);
	// Clean temp animation
	animation.Clear();
	// Dead Left
	animation.AddFrame(Frame({ 96.0f, 544.0f }, { 16.0f, 382.0f, 163.0f, 544.0f }, {}, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 244.0f, 544.0f }, { 182.0f, 366.0f, 319.0f, 544.0f }, {}, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 384.0f, 544.0f }, { 341.0f, 413.0f, 485.0f, 544.0f }, {}, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 544.0f, 544.0f }, { 502.0f, 450.0f, 644.0f, 544.0f }, {}, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 704.0f, 544.0f }, { 661.0f, 463.0f, 805.0f, 544.0f }, {}, 0.0f, 0.25f, -1, true));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("LockJawDeadLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Dead Right
	animation.AddFrame(Frame({ 96.0f, 544.0f }, { 16.0f, 382.0f, 163.0f, 544.0f }, {}, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 244.0f, 544.0f }, { 182.0f, 366.0f, 319.0f, 544.0f }, {}, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 384.0f, 544.0f }, { 341.0f, 413.0f, 485.0f, 544.0f }, {}, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 544.0f, 544.0f }, { 502.0f, 450.0f, 644.0f, 544.0f }, {}, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 704.0f, 544.0f }, { 661.0f, 463.0f, 805.0f, 544.0f }, {}, 0.0f, 0.25f));
	animation.IsLooping(false);
	// Insert animation into animation manager
	am->AddAnimation("LockJawDeadRight", animation);
	// Clean temp animation
	animation.Clear();

	// Crumbling Platform Object
	// Set Image
	animation.SetImage(hCrumblingPlatformImage);
	// - Just Single Frame
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("CrumblingPlatform", animation);
	// Clean temp animation
	animation.Clear();

	// Checkpoint
	// Set Image
	animation.SetImage(hCheckPointImage);
	// Add Frame
	animation.AddFrame(Frame({ 84.0f, 117.0f }, { 2.0f, 7.0f, 165.0f, 117.0f }, { 2.0f, 7.0f, 165.0f, 117.0f }));
	// Insert animation into animation manager
	am->AddAnimation("CheckPoint", animation);	
	// Clean temp animation
	animation.Clear();

	// Honey Badger Enemy
	animation.SetImage(hEnemyImage);
	// Standing Right
	animation.AddFrame(Frame({ 480.0f, 227.0f }, { 441.0f, 121.0f, 516.0f, 227.0f }, { 464.0f, 131.0f, 507.0f, 227.0f }, 0.0f, 0.2f));
	// Insert animation into animation manager
	am->AddAnimation("EnemyStandingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Standing Left
	animation.AddFrame(Frame({ 480.0f, 227.0f }, { 441, 121.0f, 516.0f, 227.0f }, { 464.0f, 131.0f, 507.0f, 227.0f }, 0.0f, 0.2f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("EnemyStandingLeft", animation);
	// Walking Right Animation 
	animation.AddFrame(Frame({ 480.0f, 227.0f }, { 441.0f, 121.0f, 516.0f, 227.0f }, { 464.0f, 131.0f, 507.0f, 227.0f }, 0.0f, 0.2f));
	animation.AddFrame(Frame({ 598.0f, 231.0f }, { 568.0f, 121.0f, 632.0f, 231.0f }, { 584.0f, 130.0f, 626.0f, 231.0f }, 0.0F, 0.2f));
	animation.AddFrame(Frame({ 713.0f, 230.0f }, { 681.0f, 121.0f, 738.0f, 230.0f }, { 694.0f, 130.0f, 733.0f, 230.0f }, 0.0F, 0.2f));
	// Insert animation into animation manager
	am->AddAnimation("EnemyWalkingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Walking Left Animation
	animation.AddFrame(Frame({ 480.0f, 227.0f }, { 441, 121.0f, 516.0f, 227.0f }, { 464.0f, 131.0f, 507.0f, 227.0f }, 0.0f, 0.2f, -1, true));
	animation.AddFrame(Frame({ 598.0f, 231.0f }, { 568, 121.0f, 632.0f, 231.0f }, { 584.0f, 130.0f, 626.0f, 231.0f }, 0.0f, 0.2f, -1, true));
	animation.AddFrame(Frame({ 713.0f, 230.0f }, { 681, 121.0f, 738.0f, 230.0f }, { 694.0f, 130.0f, 733.0f, 230.0f }, 0.0f, 0.2f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("EnemyWalkingLeft", animation);
	// Clean temp animation
	animation.Clear();
	// Attacking Right Animation
	animation.AddFrame(Frame({ 877.0f, 234.0f }, { 842.0f, 125.0f, 907.0f, 234.0f }, { 860.0f, 134.0f, 900.0f, 234.0f }, 0.0f, 0.25f));
	animation.AddFrame(Frame({ 902.0f, 354.0f }, { 875.0f, 247.0f, 960.0f, 354.0f }, { 896.0f, 257.0f, 952.0f, 354.0f }, 0.0f, 0.25f));
	// Insert animation into animation manager
	am->AddAnimation("EnemyAttackingRight", animation);
	// Clean temp animation
	animation.Clear();
	// Attacking left Animation
	animation.AddFrame(Frame({ 877.0f, 234.0f }, { 842.0f, 125.0f, 907.0f, 234.0f }, { 860.0f, 134.0f, 900.0f, 234.0f }, 0.0f, 0.25f, -1, true));
	animation.AddFrame(Frame({ 902.0f, 354.0f }, { 875.0f, 247.0f, 960.0f, 354.0f }, { 896.0f, 257.0f, 952.0f, 354.0f }, 0.0f, 0.25f, -1, true));
	// Insert animation into animation manager
	am->AddAnimation("EnemyAttackingLeft", animation);
	// Clean temp animation
	animation.Clear();
	
	// Health Power Up
	// Set Image
	animation.SetImage(hHPBoostImage);
	// Add Frame
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }));
	// Insert animation into animation manager
	am->AddAnimation("HPPowerUp", animation);
	// Clean temp animation
	animation.Clear();

	// Damage Power Up
	// Set Image
	animation.SetImage(hDamageBoostImage);
	// Add Frame
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }));
	// Insert animation into animation manager
	am->AddAnimation("DamagePowerUp", animation);
	// Clean temp animation
	animation.Clear();

	// Speed Power Up
	// Set Image
	animation.SetImage(hSpeedBoostImage);
	// Add Frame
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }));
	// Insert animation into animation manager
	am->AddAnimation("SpeedPowerUp", animation);
	// Clean temp animation
	animation.Clear();

	// Spike
	// Set Image
	animation.SetImage(hSpikeImage);
	// Add Frame
	animation.AddFrame(Frame({ 16.0f, 31.0f }, { 0.0f, 0.0f, 31.0f, 31.0f }, { 1.0f, 1.0f, 30.0f, 31.0f }));
	// Insert animation into animation manager
	am->AddAnimation("Spike", animation);
	// Clean temp animation
	animation.Clear();


	// Liquid - No image
	animation.SetImage(SGD::INVALID_HANDLE);
	// Animation Frame
	animation.AddFrame(Frame({ 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 5.0f, 32.0f, 32.0f }));
	// Insert animation into animation manager
	am->AddAnimation("Liquid", animation);
	// Clean temp animation
	animation.Clear();

	// Projectile
	// Set Image
	animation.SetImage(hProjectileImage);
	// Add Frame
	animation.AddFrame(Frame({ 13.0f, 13.0f }, { 0.0f, 0.0f, 26.0f, 26.0f }, { 0.0f, 0.0f, 26.0f, 26.0f }));
	// Insert animation into animation manager
	am->AddAnimation("Projectile", animation);
	// Clean temp animation
	animation.Clear();

	/// Add further animations HERE

	// Lava
	animation.SetImage(hLavaImage);
	animation.AddFrame(Frame({ 0.0f, 0.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 5.0f, 32.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 0.0f }, { 32.0f, 0.0f, 64.0f, 32.0f }, { 32.0f, 5.0f, 64.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 32.0f, 32.0f, 64.0f }, { 0.0f, 37.0f, 32.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 32.0f }, { 32.0f, 32.0f, 64.0f, 64.0f }, { 32.0f, 37.0f, 64.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.IsLooping(true);
	animation.IsPlaying(true);
	am->AddAnimation("Lava", animation);
	animation.Clear();

	// Water
	animation.SetImage(hWaterImage);
	animation.AddFrame(Frame({ 0.0f, 0.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 5.0f, 32.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 0.0f }, { 32.0f, 0.0f, 64.0f, 32.0f }, { 32.0f, 5.0f, 64.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 32.0f, 32.0f, 64.0f }, { 0.0f, 37.0f, 32.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 32.0f }, { 32.0f, 32.0f, 64.0f, 64.0f }, { 32.0f, 37.0f, 64.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.IsLooping(true);
	animation.IsPlaying(true);
	am->AddAnimation("Water", animation);
	animation.Clear();

	// Quicksand
	animation.SetImage(hQuicksandImage);
	animation.AddFrame(Frame({ 0.0f, 0.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 5.0f, 32.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 0.0f }, { 32.0f, 0.0f, 64.0f, 32.0f }, { 32.0f, 5.0f, 64.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 32.0f, 32.0f, 64.0f }, { 0.0f, 37.0f, 32.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 32.0f }, { 32.0f, 32.0f, 64.0f, 64.0f }, { 32.0f, 37.0f, 64.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.IsLooping(true);
	animation.IsPlaying(true);
	am->AddAnimation("Quicksand", animation);
	animation.Clear();

	// Quicksand Surface
	animation.SetImage(hQuicksandSurfaceImage);
	animation.AddFrame(Frame({ 0.0f, 0.0f }, { 0.0f, 0.0f, 32.0f, 32.0f }, { 0.0f, 5.0f, 32.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 0.0f }, { 32.0f, 0.0f, 64.0f, 32.0f }, { 32.0f, 5.0f, 64.0f, 32.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 0.0f, 32.0f }, { 0.0f, 32.0f, 32.0f, 64.0f }, { 0.0f, 37.0f, 32.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.AddFrame(Frame({ 32.0f, 32.0f }, { 32.0f, 32.0f, 64.0f, 64.0f }, { 32.0f, 37.0f, 64.0f, 64.0f }, 0.0f, 0.1f, -1));
	animation.IsLooping(true);
	animation.IsPlaying(true);
	am->AddAnimation("QuicksandSurface", animation);
	animation.Clear();
}

void Game::SetBGM(char* song)
{
	if (hBackgroundMus != SGD::INVALID_HANDLE)
		AUDIO->UnloadAudio(hBackgroundMus);
	hBackgroundMus = AUDIO->LoadAudio(song);
}

void Game::PlayBGM(bool play)
{
	if (play && !AUDIO->IsAudioPlaying(hBackgroundMus))
		AUDIO->PlayAudio(hBackgroundMus, true);
	else if (!play && hBackgroundMus != SGD::INVALID_HANDLE)
		AUDIO->StopAudio(hBackgroundMus);
}

char* Game::GetCurrentObjects()
{
	return cObjects;
}

void Game::SetCurrentObjects(char* objects)
{
	cObjects = objects;
}

// FACTORY METHODS!!!!!

void Game::CreateEnemy(SGD::Point pos, int id)
{
	Enemy* enemy = new Enemy();
	enemy->SetPosition(pos);
	enemy->SetSize(SGD::Size{ 84, 109 });
	enemy->SetAcceleration(SGD::Vector{ 100, 0 });
	enemy->SetMaxSpeed(100.0f);
	enemy->SetDamage(10);
	enemy->SetMaxHP(30);
	enemy->SetCurrentHP(enemy->GetMaxHP());
	enemy->SetPatrolPointLeft(SGD::Point(pos.x - 200, 0));
	enemy->SetPatrolPointRight(SGD::Point(pos.x + 200, 0));
	if (id == GameObject::ObjectID::MELEE)
	{	
		enemy->SetAttackResetTime(1.5f);
		enemy->SetID(GameObject::ObjectID::MELEE);
	}
	else
	{
		enemy->SetAttackResetTime(2.0f);
		enemy->SetID(GameObject::ObjectID::RANGED);
	}
		enemy->SetAnimation("EnemyWalkingLeft");

	Emitter* e = new Emitter(*particleManager->operator[](1));
	e->Load();
	enemy->AddEmitter(e);

	GAME->GetEntityManager().AddEntity(enemy, 1);
	enemy->Release();
}

void Game::CreatePlayer(SGD::Point pos)
{
	GAME->SetPlayer(new Player);
	Player* player = GAME->GetPlayer();
	player->SetPosition(pos);
	player->SetSize(SGD::Size{ 60, 76 });
	player->SetMaxSpeed(1000.0f);
	player->SetDamage(10);
	player->SetMaxHP(100);
	player->SetCurrentHP(100);
	player->SetID(GameObject::ObjectID::PLAYER);
	Emitter* e = new Emitter(*particleManager->operator[](0));
	e->Load();
	player->AddEmitter(e);

	// Add Player To pObjects
	GAME->GetEntityManager().AddEntity(player, 0);
}

void Game::CreateHPPowerUp(SGD::Point pos, int id)
{
	PowerUps* HPPowerUp = new PowerUps();
	HPPowerUp->SetHPPowerUp(50);
	HPPowerUp->SetPosition(SGD::Point{ pos.x + 16, pos.y + 32 });
	HPPowerUp->SetSize(SGD::Size{ 32, 32 });
	HPPowerUp->SetID(id);
	HPPowerUp->SetAnimation("HPPowerUp");

	GAME->GetEntityManager().AddEntity(HPPowerUp, 3);
	HPPowerUp->Release();
}

void Game::CreateDamagePowerUp(SGD::Point pos, int id)
{
	PowerUps* DamagePowerUp = new PowerUps();
	DamagePowerUp->SetDamagePowerUp(10);
	DamagePowerUp->SetPosition(SGD::Point{ pos.x + 16, pos.y + 32 });
	DamagePowerUp->SetSize(SGD::Size{ 32, 32 });
	DamagePowerUp->SetID(id);
	DamagePowerUp->SetAnimation("DamagePowerUp");

	GAME->GetEntityManager().AddEntity(DamagePowerUp, 3);
	DamagePowerUp->Release();
}

void Game::CreateSpeedPowerUp(SGD::Point pos, int id)
{
	PowerUps* SpeedPowerUp = new PowerUps();
	SpeedPowerUp->SetSpeedPowerUp(100.0f);
	SpeedPowerUp->SetPosition(SGD::Point{ pos.x + 16, pos.y + 32 });
	SpeedPowerUp->SetSize(SGD::Size{ 32, 32 });
	SpeedPowerUp->SetID(id);
	SpeedPowerUp->SetAnimation("SpeedPowerUp");

	GAME->GetEntityManager().AddEntity(SpeedPowerUp, 3);
	SpeedPowerUp->Release();
}

void Game::CreateCheckPoint(SGD::Point pos, int id)
{
	CheckPointObject* checkPoint = new CheckPointObject();
	checkPoint->SetPosition(SGD::Point{pos.x, pos.y + 32});
	checkPoint->SetSize(SGD::Size{ 128, 128 });
	checkPoint->SetID(id);
	checkPoint->SetAnimation("CheckPoint");
	checkpointLoc = pos;

	GAME->GetEntityManager().AddEntity(checkPoint, 10);
	checkPoint->Release();
}

void Game::CreateCrumblingPlatform(SGD::Point pos, int id)
{
	CrumblingPlatformObject* crumblingPlatform = new CrumblingPlatformObject();
	crumblingPlatform->SetPosition(SGD::Point{ pos.x, pos.y + 32 });
	crumblingPlatform->SetSize(SGD::Size{ 32, 32 });
	crumblingPlatform->SetID(id);
	crumblingPlatform->SetAnimation("CrumblingPlatform");

	GAME->GetEntityManager().AddEntity(crumblingPlatform, 9);
	crumblingPlatform->Release();
}

WallTriggerObject* Game::CreateWallTriggerObject(SGD::Point pos, int id, unsigned int ownerID)
{
	WallTriggerObject* wallObject = new WallTriggerObject(ownerID);
	wallObject->SetPosition(SGD::Point{ pos.x, pos.y + 32 });
	wallObject->SetSize(SGD::Size{ 32, 32 });
	wallObject->SetID(id);
	wallObject->SetAnimation("WallTrigger");

	GAME->GetEntityManager().AddEntity(wallObject, 7);

	wallObject->Release();
	return wallObject;
}

void Game::CreateSpike(SGD::Point pos, int id)
{
	SpikeObject* spike = new SpikeObject();
	spike->SetPosition(SGD::Point{pos.x + 16, pos.y + 32});
	spike->SetSize(SGD::Size{ 64, 128 });
	spike->SetID(id);
	spike->SetAnimation("Spike");
	GAME->GetEntityManager().AddEntity(spike, 11);
	spike->Release();
}

void Game::CreateSpringboard(SGD::Point pos, int id)
{
	SpringboardObject* spring = new SpringboardObject();
	spring->SetPosition(SGD::Point{ pos.x, pos.y + 32 });
	spring->SetSize(SGD::Size{ 32, 32 });
	spring->SetID(id);
	spring->SetAnimation("Springboard");

	GAME->GetEntityManager().AddEntity(spring, 12);
	spring->Release();
}

void Game::CreateSwitchTrigger(SGD::Point pos, int id, unsigned int targetID)
{
	SwitchTriggerObject* switchTrigger = new SwitchTriggerObject(targetID);
	switchTrigger->SetPosition(SGD::Point{ pos.x, pos.y + 32 });
	switchTrigger->SetSize(SGD::Size{ 32, 16 });
	switchTrigger->SetID(id);
	switchTrigger->SetAnimation("SwitchTriggerUp");

	GAME->GetEntityManager().AddEntity(switchTrigger, 8);
	switchTrigger->Release();
}

void Game::CreateEventt(SGD::Point pos)
{
	Event* eventt = new Event();
	eventt->SetPosition(pos);


	GAME->GetEntityManager().AddEntity(eventt, 5);
	eventt->Release();
}

void Game::CreateProjectile(SGD::Point pos, SGD::Vector vec, bool facingLeft)
{
	Projectile* projectile = new Projectile;
	projectile->SetPosition(pos);
	projectile->SetSize(SGD::Size{ 26, 26 });
	projectile->SetDamage(10);
	projectile->SetMaxSpeed(500);

	if (facingLeft)
	{
		projectile->SetAcceleration(SGD::Vector{ vec.x *100.0f, vec.y * 100.0f });
		projectile->SetVelocity(SGD::Vector{ vec.x, vec.y });
	}
	else
	{
		projectile->SetAcceleration(SGD::Vector{ vec.x * 100.0f, vec.y * 100.0f });
		projectile->SetVelocity(SGD::Vector{ vec.x, vec.y });
	}

	// Add Projectile To pObjects
	GAME->GetEntityManager().AddEntity(projectile, 3);
	projectile->Release();
}

void Game::CreateLiquid(SGD::Point pos, int damage, int level)
{
	Liquid* liquid = new Liquid(damage);
	liquid->SetPosition(pos);

	if (level == 3)
		liquid->SetAnimation("Quicksand");
	else
		liquid->SetAnimation("Liquid");

	GAME->GetEntityManager().AddEntity(liquid, 3);
	liquid->Release();
}

void Game::CreateSurfaceLiquid(SGD::Point pos, int damage, int level)
{
	Liquid* liquid = new Liquid(damage);
	liquid->SetPosition(pos);

	if (level == 1)
		liquid->SetAnimation("Water");
	else if (level == 2)
	{
		Emitter* e = new Emitter(*particleManager->operator[](2));
		e->Load();
		e->SetPlay(true);
		liquid->AddEmitter(e);
	}
	else if (level == 3)
		liquid->SetAnimation("QuicksandSurface");
	else if (level == 4)
		liquid->SetAnimation("Lava");
	else
		liquid->SetAnimation("Liquid");

	GAME->GetEntityManager().AddEntity(liquid, 3);
	liquid->Release();
}


void Game::CreateBoss(SGD::Point pos, int id, int level)
{
	Boss* boss = new Boss();
	boss->SetPosition(pos);
	boss->SetAttackResetTime(2.5f);
	if (level == 1)
	{
		boss->SetAnimation("QudzuIdleLeft");
		boss->SetSize(SGD::Size{ 130, 130 });
		boss->SetAcceleration(SGD::Vector{ 100, 0 });
		boss->SetMaxSpeed(100.0f);
		boss->SetDamage(15);
		boss->SetMaxHP(100);
		boss->SetID(GameObject::ObjectID::QUDZU);
		boss->SetCurrentHP(boss->GetMaxHP());
	}
	else if (level == 2)
	{
		boss->SetAnimation("PapaBearIdleLeft");
		boss->SetSize(SGD::Size{ 130, 130 });
		boss->SetAcceleration(SGD::Vector{ 100, 0 });
		boss->SetMaxSpeed(100.0f);
		boss->SetDamage(20);
		boss->SetMaxHP(150);
		boss->SetID(GameObject::ObjectID::PAPABEAR);
		boss->SetCurrentHP(boss->GetMaxHP());
	}
	else if (level == 3)
	{
		boss->SetAnimation("PapaBearIdleLeft");
		boss->SetSize(SGD::Size{ 116, 126 });
		boss->SetAcceleration(SGD::Vector{ 100, 0 });
		boss->SetMaxSpeed(200.0f);
		boss->SetDamage(25);
		boss->SetMaxHP(200);
		boss->SetID(GameObject::ObjectID::PAPABEAR);
		boss->SetCurrentHP(boss->GetMaxHP());
	}
	else if (level == 4)
	{
		boss->SetAnimation("LockJawStandingLeft");
		boss->SetSize(SGD::Size{ 116, 126 });
		boss->SetAcceleration(SGD::Vector{ 100, 0 });
		boss->SetMaxSpeed(200.0f);
		boss->SetDamage(20);
		boss->SetMaxHP(250);
		boss->SetID(GameObject::ObjectID::LOCKJAW);
		boss->SetCurrentHP(boss->GetMaxHP());
		// Give Lock Jaw a restraint for the cave level
		boss->SetPatrolPointLeft(SGD::Point{ pos.x - 550, 0 });
	}
	Emitter* e = new Emitter(*particleManager->operator[](1));
	e->Load();
	boss->AddEmitter(e);

	GAME->GetEntityManager().AddEntity(boss, 2);
	boss->Release();
}

SGD::Point Game::GetCheckpointLoc()
{
	return checkpointLoc;
}

int Game::GetBottomOfLevel()
{
	return iBottomLevel;
}

void Game::SetBottomOfLevel(int bottom)
{
	iBottomLevel = bottom;
}


// Time Attack
float Game::GetTimeAttackTime()
{
	return fTimeAttack;
}
void Game::SetTimeAttackTime(float time)
{
	fTimeAttack = time;
}
void Game::ResetTimeAttackTime()
{
	fTimeAttack = 1200.0f;
}
void Game::PauseTimeAttack(bool pause)
{
	bTimeAttackPause = pause;
}
bool Game::IsTimeAttackPaused()
{
	return bTimeAttackPause;
}

int Game::GetTimeAttackLevel()
{
	return iTimeAttackLevel;
}

void Game::SetTimeAttackLevel(int level)
{
	iTimeAttackLevel = level;
}

bool Game::GetInput()
{
	return bInput;
}

void Game::SetInput(bool input)
{
	bInput = input;
}

int Game::GetHighScore(int index)
{
	return vecHighScores[index];
}

void Game::AddHighScore(float score)
{
	float time = score;
	int minutes, seconds, milliseconds;
	if (time > 0.0f)
	{
		seconds = (int)time;
		milliseconds = (int)((time - seconds) * 100);  // truncating to increments of 10 milliseconds
		minutes = seconds / 60;
		seconds %= 60;
	}

	int newScore;

	minutes *= 10000;
	seconds *= 100;

	newScore = minutes + seconds + milliseconds;

	vecHighScores.push_back(newScore);

	SortHighScores();
}

void Game::SortHighScores()
{
	for (unsigned int x = 0; x < vecHighScores.size(); x++)
	{
		for (unsigned int y = 0; y < vecHighScores.size(); y++)
		{
			if (vecHighScores[x] > vecHighScores[y])
			{
				std::swap(vecHighScores[x], vecHighScores[y]);
			}
		}
	}

	if (vecHighScores.size() > 5)
	{
		for (unsigned int i = 0; i < vecHighScores.size() - 5; i++)
		{
			vecHighScores.pop_back();
		}
	}
}

void Game::LoadHighScores()
{
	std::wstring filePath = GetFilePath();

	filePath += L"\\highscores.txt";

	std::fstream file;
	file.open(filePath.c_str(), std::ios_base::in);

	if (file.is_open())
	{
		int score;

		while (true)
		{
			if (file.eof())
				break;

			file >> score;

			file.ignore(INT_MAX, '\n');

			vecHighScores.push_back(score);
		}

		file.close();
	}

	if (vecHighScores.size() <= 0)
	{
		vecHighScores.push_back(31558);
		vecHighScores.push_back(85523);
		vecHighScores.push_back(114214);
		vecHighScores.push_back(134653);
		vecHighScores.push_back(170231);
	}
}

void Game::SaveHighScores()
{
	std::wstring filePath = GAME->GetFilePath();
	filePath += L"\\highscores.txt";

	std::ofstream fout;
	fout.open(filePath);

	if (fout.is_open())
	{
		for (unsigned int i = 0; i < vecHighScores.size(); i++)
		{
			fout << vecHighScores[i] << '\n';
		}

		fout.close();
	}
}

bool Game::HasBeatTimeAttack()
{
	return bBeatTimeAttack;
}

void Game::SetBeatTimeAttack(bool win)
{
	bBeatTimeAttack = win;
}